import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import * as bcrypt from 'bcryptjs';
import { Role } from '../role/entities/role.entity';
import { AssignRoleDto } from './dto/assign-role.dto';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    @InjectRepository(Role)
    private readonly roleRepository: Repository<Role>,
  ) {}

  // 创建单个用户
  async create(createUserDto: CreateUserDto): Promise<User> {
    const roleName = createUserDto.role?.name;
    console.log('user.service.ts-create-role', createUserDto);

    // 如果没有传递角色名，设置为游客角色
    const role = roleName
      ? await this.roleRepository.findOne({ where: { name: roleName } })
      : await this.roleRepository.findOne({ where: { name: '访客' } });

    if (!role) {
      throw new Error('指定的角色不存在');
    }
    // Hash the password before saving to the database
    const hashedPassword = await bcrypt.hash(createUserDto.password, 10); // '10' is the salt rounds

    // Create a new user object with the hashed password
    const user = this.userRepository.create({
      ...createUserDto,
      password: hashedPassword, // Use the hashed password
    });
    user.role = role;

    // Save the user and return the saved user object
    return this.userRepository.save(user);
  }

  // 为用户分配角色
  async assignRole(assignRoleDto: AssignRoleDto): Promise<User> {
    const { userId, roleId } = assignRoleDto;

    // 查找用户
    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException('用户未找到');
    }

    // 查找角色
    const role = await this.roleRepository.findOne({ where: { id: roleId } });
    if (!role) {
      throw new NotFoundException('角色未找到');
    }

    // 分配角色给用户
    user.role = role; // 如果是多对多关系，可以使用 `user.roles.push(role)` 或类似方法

    // 保存用户
    await this.userRepository.save(user);

    return user;
  }

  // 查询所有用户
  async findAll(): Promise<User[]> {
    return this.userRepository.find({
      relations: ['role'],
    });
  }

  // 根据ID查询用户
  async findOne(id: string): Promise<User> {
    return this.userRepository.findOneById(id);
  }

  // 更新用户
  async update(id: string, updateUserDto: UpdateUserDto): Promise<User> {
    await this.userRepository.update(id, updateUserDto);
    return this.userRepository.findOneById(id);
  }

  // 删除用户
  async remove(id: string): Promise<void> {
    await this.userRepository.delete(id);
  }

  // 批量创建用户
  async createBulk(createUserDtos: CreateUserDto[]): Promise<User[]> {
    const users = this.userRepository.create(createUserDtos);
    return await this.userRepository.save(users);
  }

  // 批量删除用户
  async removeBulk(ids: string[]): Promise<void> {
    await this.userRepository.delete(ids);
  }

  // Method to find user by username or email
  async findByUsernameOrEmail(
    usernameOrEmail: string,
  ): Promise<User | undefined> {
    // Check if the input is an email using a basic regex
    const isEmail = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/.test(
      usernameOrEmail,
    );

    // If it's an email, query the database by email; otherwise, query by username
    if (isEmail) {
      return this.userRepository.findOne({ where: { email: usernameOrEmail } });
    } else {
      return this.userRepository.findOne({
        where: { username: usernameOrEmail },
      });
    }
  }
}
